package com.ccp.dev.system.model.util;

import com.ccp.dev.core.basic.annotion.Action;
import com.ccp.dev.core.basic.util.PinyinUtil;
import com.ccp.dev.system.model.menuauto.ClassInfoModel;
import com.ccp.dev.system.model.menuauto.MethodInfoModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 获取类上的RequestMapping注解
 * 获取方法上的RequestMapping及Action注解。
 * map注解的value作为菜单的URL，action注解的description作为菜单的名称
 * @author Administrator
 *
 */
public class GetAllMenuPath {

	public static final String URL_PRE = "";
	
	/**
	 * 获取Controller类中的URL
	 * @param onlyThisUrl 只获取制定的URL数据
	 * @return
	 * @throws Exception
	 */
	/**
	 * 
	 * @param packagePath 需要扫描的包路径
	 * @param notScanList 包路径中不需要扫描的子包的名称
	 * @param onlyThisUrl 指定处理的URL，其它的不再处理
	 * @return 类及方法数据
	 * @throws Exception 抛出异常
	 */
	public static List<ClassInfoModel> GetAllMenuPath(String packagePath, List<String> notScanList, String onlyThisUrl) throws Exception {
		List<Class<?>> list = new ArrayList<Class<?>>();
		Class<?>  cla = Class.forName(packagePath);
		list.add(cla);
		List<ClassInfoModel> classInfoModelList = new ArrayList<>();
		ClassInfoModel classInfoModel;
		for (Class<?> objectClass : list) {
			classInfoModel = new ClassInfoModel();
			List<MethodInfoModel> methodInfoModelList = new ArrayList<>();
			Annotation[] classAnnotation = objectClass.getAnnotations();
			String classReqMapValue = "";
			for (Annotation annotation : classAnnotation) {
				Class<? extends Annotation> annotationType = annotation.annotationType();
				if (annotationType == RequestMapping.class || annotationType == PostMapping.class || annotationType == GetMapping.class) {
					if(annotation instanceof RequestMapping){
						classReqMapValue = ((RequestMapping)annotation).value()[0];
					}else if(annotation instanceof GetMapping){
						classReqMapValue = ((GetMapping)annotation).value()[0];
					}else{
						classReqMapValue = ((PostMapping)annotation).value()[0];
					}
				}
			}
			classInfoModel.setClssName(objectClass.getSimpleName());//FIXME 试一下这个简短名称
			classInfoModel.setClassReqMapValue(classReqMapValue);
			MethodInfoModel methodInfoModel;
			Method[] methodList = objectClass.getDeclaredMethods();
			for (Method method : methodList) {
				Annotation[] annotations = method.getAnnotations();
				if(annotations.length>0){
					methodInfoModel = new MethodInfoModel();
					methodInfoModel.setMethodName(method.getName());//设置方法名称
					boolean enableMethod = false;
					for (Annotation annotation : annotations) {
						// 获取注解的具体类型
						Class<? extends Annotation> annotationType = annotation.annotationType();
						if (annotationType == RequestMapping.class || annotationType == PostMapping.class || annotationType == GetMapping.class) {
							String[] reqVal = null;
							if(annotation instanceof RequestMapping){
								reqVal = ((RequestMapping)annotation).value();
							}else if(annotation instanceof GetMapping){
								reqVal = ((GetMapping)annotation).value();
							}else{
								reqVal = ((PostMapping)annotation).value();
							}
							if(reqVal.length<=0){
								//logincontroller中是按照类路径配置，直接访问
//								System.out.println("方法需要按照类路径访问。。。。。"+classInfoModel+"方法数据="+methodInfoModel);
								break;
							}else{
								String methodUrl = null;
								if(annotation instanceof RequestMapping){
									methodUrl = ((RequestMapping)annotation).value()[0]+URL_PRE;
								}else if(annotation instanceof GetMapping){
									methodUrl = ((GetMapping)annotation).value()[0]+URL_PRE;
								}else{
									methodUrl = ((PostMapping)annotation).value()[0]+URL_PRE;
								}
								//如果指定了处理的URL且当前的不匹配，则直接break
								if(StringUtils.isNotBlank(onlyThisUrl) && !methodUrl.equals(onlyThisUrl)){
									break;
								}else{
									if(methodUrl.contains("{")){
//										System.out.println("存在URL参数配置。。。。。"+classInfoModel+"方法数据="+methodInfoModel);
										break;
									}else{
										enableMethod = true;
										methodInfoModel.setMethodReqMapValue(methodUrl);//设置方法上的RequestMapping路径
										methodInfoModel.setCompleteUrl(classReqMapValue+methodUrl);//完整的URL路径
										//处理是否显示到菜单、是否有子菜单
										boolean inMenuAndChildren = inMenuAndChildren(methodUrl);
										methodInfoModel.setShowInMenu(inMenuAndChildren);
										methodInfoModel.setHasChildren(inMenuAndChildren);
									}
								}
							}
						} else if (Action.class == annotationType) {
							enableMethod = true;
							Action action = (Action) annotation;
							//需要转换一下拼音 菜单别名，
							String description = action.description();
							methodInfoModel.setActionDesc(description);
							methodInfoModel.setActionDescPY(description);
						}
					}
					if(enableMethod && StringUtils.isNotBlank(methodInfoModel.getMethodReqMapValue())){
						if(StringUtils.isBlank(methodInfoModel.getActionDesc()) || methodInfoModel.getActionDesc()==null || methodInfoModel.getActionDesc().length()==0){
							String descWithOutAction = classInfoModel.getClssName()+"\\"+methodInfoModel.getMethodName();//TODO 优化资源名称默认定义
							methodInfoModel.setActionDesc(descWithOutAction);
							methodInfoModel.setActionDescPY(PinyinUtil.getPinYinHeadCharFilter(descWithOutAction));
						}else{
							String description = methodInfoModel.getActionDesc();
							String newDesc = getDescription(methodInfoModel.getMethodReqMapValue(),description);
							methodInfoModel.setActionDesc(newDesc);
							methodInfoModel.setActionDescPY(PinyinUtil.getPinYinHeadCharFilter(newDesc));
						}
						methodInfoModelList.add(methodInfoModel);
						enableMethod = false;
					}
				}
			}
			classInfoModel.setMethodInfoModelList(methodInfoModelList);
			classInfoModelList.add(classInfoModel);
		}
		return classInfoModelList;
	}
	
	/**
	 * 判断是否显示到菜单，只有list.ht显示到菜单、是否有子菜单
	 * @param methodUrl 方法注解，已拼接了.ht
	 * @return 如果显示到菜单则返回true
	 */
	public static boolean inMenuAndChildren(String methodUrl) {
		if(methodUrl.equalsIgnoreCase("list"+URL_PRE)){
			return true;
		}
		return false;
	}

	/**
	 * 处理资源的名称,根据文档中的规则进行定义，list加列表，del加删除，edit加编辑，save加保存，其它的不加前缀
	 * @param reqMapVal Controller中方法上注解的URL
	 * @param oriDesc Controller中方法上注解的资源名称
	 * @return返回处理过的资源名称 
	 */
	public static String getDescription(String reqMapVal,String oriDesc){
		if( !reqMapVal.startsWith("list") && (reqMapVal.indexOf("list")>=0 ||reqMapVal.indexOf("List")>=0)){
			return  "列表-"+oriDesc;
		}//TODO 完善代码 是代码中不出现中文
		if(!reqMapVal.startsWith("save") && (reqMapVal.indexOf("save")>=0 ||reqMapVal.indexOf("Save")>=0)){
			return  "保存-"+oriDesc;
		}
		if(!reqMapVal.startsWith("edit") && (reqMapVal.indexOf("edit")>=0 ||reqMapVal.indexOf("Edit")>=0)){
			return  "编辑-"+oriDesc;
		}
		if(!reqMapVal.startsWith("modif") && (reqMapVal.indexOf("modif")>=0 ||reqMapVal.indexOf("Modif")>=0)){
			return  "编辑-"+oriDesc;
		}
		if(!reqMapVal.startsWith("del") && (reqMapVal.indexOf("del")>=0 ||reqMapVal.indexOf("Del")>=0)){
			return  "删除-"+oriDesc;
		}
		if(!reqMapVal.startsWith("get") && (reqMapVal.indexOf("get")>=0 ||reqMapVal.indexOf("get")>=0)){
			return  "获取-"+oriDesc;
		}
		return oriDesc;
	}

}
